import axios from 'axios';
import { TopicContent } from './search-processor.js';

export class AnswerGenerator {
  private apiKey: string;
  private modelName: string;
  private maxPreviewLength: number = 250; // 预览长度限制
  private maxContentPerTopic: number = 1500; // 每个主题内容长度限制

  constructor(apiKey: string, modelName: string = 'qwen-plus') {
    this.apiKey = apiKey;
    this.modelName = modelName;
  }

  /**
   * 生成回答
   */
  public async generateAnswer(query: string, searchResults: TopicContent[]): Promise<string> {
    try {
      console.log('开始生成回答...');
      
      // 生成预览文本，方便调试
      this.generatePreview(searchResults);
      
      // 格式化上下文
      const formattedContext = this.formatContext(searchResults);
      
      // 生成提示词
      const prompt = this.generatePrompt(query, formattedContext);
      
      // 调用阿里云通义千问兼容OpenAI的API
      const response = await axios.post(
        'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
        {
          model: this.modelName,
          messages: [
            {
              role: 'system',
              content: '你是一个基于水源社区信息的智能助手。根据提供的上下文内容回答用户的问题。如果上下文中没有相关信息，请诚实地告知你不知道。'
            },
            {
              role: 'user',
              content: prompt
            }
          ],
          temperature: 0.7,
          max_tokens: 800
        },
        {
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          }
        }
      );
      
      // 提取回答
      const answer = response.data?.choices?.[0]?.message?.content || '抱歉，无法生成回答。';
      console.log('回答生成完成');
      
      // 尝试保存大模型输入用于调试
      this.saveDebugInfo(prompt);
      
      return answer;
    } catch (error) {
      console.error('生成回答失败:', error instanceof Error ? error.message : String(error));
      if (axios.isAxiosError(error) && error.response) {
        console.error('API错误详情:', JSON.stringify(error.response.data, null, 2));
      }
      throw new Error('生成回答失败');
    }
  }

  /**
   * 生成搜索结果的预览文本
   */
  private generatePreview(searchResults: TopicContent[]): void {
    // 按照相关性排序
    const sortedResults = [...searchResults].sort((a, b) => b.relevance - a.relevance);
    
    console.log('\n============ 搜索结果预览 ============');
    for (let i = 0; i < Math.min(sortedResults.length, 5); i++) {
      const topic = sortedResults[i];
      
      console.log(`【${i+1}】${topic.title} (回复数: ${topic.posts_count})`);
      console.log(`链接: ${topic.url}`);
      console.log(`作者: ${topic.username} | 发布时间: ${new Date(topic.created_at).toLocaleString()}`);
      console.log(`相关度得分: ${topic.relevance}`);
      console.log(`\n关键内容预览:`);
      console.log(topic.preview_content);
      console.log('\n---------------------------\n');
    }
    console.log('======================================\n');
  }

  /**
   * 保存调试信息到文件
   */
  private saveDebugInfo(prompt: string): void {
    try {
      const fs = require('fs');
      fs.writeFileSync('debug_llm_input.txt', `【大模型输入内容】\n\n${prompt}`, 'utf8');
      console.log('已保存大模型输入内容到debug_llm_input.txt');
    } catch (error) {
      console.warn('保存调试信息失败:', error instanceof Error ? error.message : String(error));
    }
  }

  /**
   * 格式化上下文
   */
  private formatContext(searchResults: TopicContent[]): string {
    if (!searchResults || searchResults.length === 0) {
      return '没有找到相关信息。';
    }
    
    let context = '';
    
    // 按相关性排序，优先使用更相关的内容
    const sortedResults = [...searchResults].sort((a, b) => b.relevance - a.relevance);
    
    for (let i = 0; i < sortedResults.length; i++) {
      const result = sortedResults[i];
      
      context += `【来源 ${i + 1}】标题: ${result.title}\n`;
      context += `链接: ${result.url}\n`;
      context += `发布者: ${result.username} | 回复数: ${result.posts_count}\n`;
      context += `发布时间: ${new Date(result.created_at).toLocaleString()}\n\n`;
      
      // 使用完整内容，但限制长度
      let content = result.full_content;
      
      // 如果内容超过限制，进行截断
      if (content.length > this.maxContentPerTopic) {
        // 尝试在句号处智能截断
        const lastSentenceEnd = content.lastIndexOf('。', this.maxContentPerTopic);
        if (lastSentenceEnd > this.maxContentPerTopic * 0.7) {
          content = content.substring(0, lastSentenceEnd + 1) + "...(内容被截断)";
        } else {
          content = content.substring(0, this.maxContentPerTopic) + "...(内容被截断)";
        }
      }
      
      context += `内容:\n${content}\n`;
      
      // 添加分隔符
      if (i < sortedResults.length - 1) {
        context += '\n---\n\n';
      }
    }
    
    return context;
  }

  /**
   * 生成提示词
   */
  private generatePrompt(query: string, context: string): string {
    return `问题: ${query}\n\n以下是来自水源社区的相关信息:\n\n${context}\n\n请根据上述信息回答问题。需要考虑整个讨论的不同意见和观点，而不仅仅是主楼发言。如果上下文中没有足够的信息，请如实说明。回答中应使用丰富的格式，并在合适时引用信息来源，但不要逐条重复所有信息。`;
  }
} 